package com.sy.filter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.sy.ResultVO;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.nio.charset.StandardCharsets;
import java.io.IOException;

/**
 * @className: VerifyTokenFilter
 * @author: Mr.Liu
 * @date: 2025/11/11 10:56
 * @Version: 1.0
 * @description: jwt的过滤器
 */

@Component
@ConfigurationProperties(prefix = "jwt")
@Data
public class VerifyTokenFilter extends OncePerRequestFilter {
    private String secret;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 1. 统一设置跨域响应头（关键：所有响应都需要携带）
        setCorsHeaders(response);
        // 2. 处理 OPTIONS 预检请求（跨域请求前的预检，直接放行）
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        // 3. 乱码处理
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        // 4. 放行不需要验证的路径
        String uri = request.getRequestURI();
        if(uri.startsWith("/api")){
            filterChain.doFilter(request, response);
            return;
        }
        // 5. 验证token
        String header = request.getHeader("Authorization");
        if (header == null) {
            response.getWriter().print(JSONUtil.toJsonStr(ResultVO.error("token为空")));
            return;
        }
        // 注意：Bearer 后面有一个空格，所以是 substring(7)
        String token = header.substring(7);
        boolean verifyResult;
        try {
            verifyResult = JWTUtil.verify(token, secret.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            response.getWriter().print(JSONUtil.toJsonStr(ResultVO.error("token解析失败")));
            return;
        }
        if (!verifyResult) {
            response.getWriter().print(JSONUtil.toJsonStr(ResultVO.error("token格式错误")));
            return;
        }
        //解析payload-->超时时间
        Long expireTime = JWTUtil.parseToken(token).getPayloads().get("expire_time", Long.class);
        if (System.currentTimeMillis() > expireTime) {
            //给一个响应码
            response.setStatus(401);
            response.getWriter().print(JSONUtil.toJsonStr(ResultVO.error("token超时,请重新登录")));
            return;
        }

        // 6. token验证通过，放行
        filterChain.doFilter(request, response);
    }

    // 抽取跨域头设置方法，与CorsConfig保持一致
    private void setCorsHeaders(HttpServletResponse response) {
        // 允许的前端域名（与CorsConfig中的allowedOrigins保持一致）
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
        // 允许携带凭证（cookie、token等）
        response.setHeader("Access-Control-Allow-Credentials", "true");
        // 允许的请求头
        response.setHeader("Access-Control-Allow-Headers", "*");
        // 允许的请求方法
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT,OPTIONS");
    }
}